package com.sz.jinzheng.controller;


import com.alibaba.fastjson.JSON;
import com.sz.jinzheng.model.*;
import com.sz.jinzheng.service.RoleUsersService;
import com.sz.jinzheng.service.UserService;
import com.sz.jinzheng.until.JwtUntil;
import com.sz.jinzheng.until.UserUntil;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {
    @Resource
    private UserService userService;
    @Resource
    private UserUntil userUntil;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private JwtUntil jwtUntil;
    @Autowired
    private RoleUsersService roleUsersService;


    /**
     * 登录接口
     *
     * @param user 用户登录账号密码
     * @return
     */
    @PostMapping("/login")
    public Result login(@RequestBody User user) {
        log.info("userlogin");
        //1.根据手机号或者邮箱获取盐
        User userByPhone = userService.getUserByPhone(user.getPhone());
        if (userByPhone == null) {
            return new Result(444, "登录失败", "用户名不存在！");
        }
        String salt = userByPhone.getSalt();
        //2.将盐一起加入到用户输入的密码跟数据库对比
        String pwd = userUntil.getPwd(user.getPassword(), salt);
        user.setPassword(pwd);
        User loginUser = userService.login(user);
        if (loginUser != null) {
            log.info(user.toString() + "登录" + new Date());
            //登录之后生成token将信息存在Redis,用户的权限需要去数据库查询
            List<Role> roles = userService.getRoles(user.getPhone());
            System.out.println("roles = " + roles);
            String token = jwtUntil.createToken(user, JSON.toJSONString(roles));

            //将用户手机号作为key，user作为value
            redisTemplate.opsForValue().set(user.getPhone(), token, 60, TimeUnit.MINUTES);
            return new Result(200, "登录成功",roles.get(0), token);
        }
        return new Result(444, "登录失败", "用户名或者密码错误");
    }

    /**
     * 获取短信验证码接口
     *
     * @return //返回成功或者失败
     */
    @PostMapping("/message")
    public Result message(String phone) {
        System.out.println(phone);
        //判断手机号是否注册
        boolean b = userService.check(phone);
        if (b) {
            //没有注册
            String yzm = userUntil.getYzm(); //随机生成的验证码省去调用借口
            redisTemplate.opsForValue().set(phone, yzm, 300, TimeUnit.SECONDS);  //生成的验证码放入Redis中,有效时间5分钟
            return new Result(200, "", "获取成功，请及时验证（5分钟）");

        }

        return new Result(444, "获取失败", "手机号码已被注册！");
    }


    /**
     * 用户注册
     *
     * @param user
     * @return
     */
    @PostMapping("/register")
    public Result register(@RequestBody User user) {
        log.info(user.toString());
        String yzm = redisTemplate.opsForValue().get(user.getPhone());//用Redis中获取短信验证码
        if (!user.getMessage().equals(yzm)) {
            //验证码不正确
            return new Result(444, "注册失败", "验证码错误");
        }
        //注册成功,写到数据库中
        int i = userService.addUser(user);
        if (i == 0) {
            return new Result(444, "注册失败", "系统错误！");
        }
        Integer uid = userService.login(user).getUid();
        System.out.println(uid);
        RoleUsers roleUsers=new RoleUsers(1,uid);
        roleUsersService.addRoleUsers(roleUsers);
        return new Result(200, "注册成功", "注册成功！");
    }


    /**
     * 获取用户信息，通过token
     *
     * @param token //前端传参来的token
     * @return
     */
    @PostMapping("/getUserInRedis")
    public Result getUserInRedis(String token) {
        //根据token解析claims
        Claims claims = jwtUntil.parseToken(token);
        if (claims != null) {
            //1.获取到手机号
            String phone = claims.getSubject();
            //2.通过手机号查询user
            User user = userService.getUserByPhone(phone);
            return new Result(200, "", user);
        }
        return new Result(444, "token过期", "token过期");
    }

    /**
     * 通过token查询uid，在查询借款人相关详情表
     *
     * @param token
     * @return
     */
    @PostMapping("/getBorrowerInfoByUid")
    public Result getBorrowerInfoByUid(String token) {
        //根据token解析claims
        Claims claims = jwtUntil.parseToken(token);
        if (claims != null) {
            //1.获取到手机号
            String phone = claims.getSubject();
            //2.通过手机号查询uid
            Integer uid = userService.getUserByPhone(phone).getUid();
            //3.通过uid查询BorrowerInfo
            BorrowerInfo borrowerInfoById = userService.getBorrowerInfoById(uid);
            if (borrowerInfoById == null) {
                return new Result(444, "未实名认证", "请先实名认证");
            }

            return new Result(200, "获取成功", borrowerInfoById);
        }
        return new Result(444, "获取失败", "token过期");
    }

    /**
     * 通过token修改用户的登录信息
     * 如果token过期则需要重新登录
     *
     * @return
     */
    @PostMapping("/updateLogin")
    public Result updateLogin(@RequestBody User user) {
        String token = user.getToken();
        //根据token解析claims
        Claims claims = jwtUntil.parseToken(token);
        if (claims != null) {
            //1.获取到手机号
            String phone = claims.getSubject();
            //2.通过手机号查询uid
            User userByPhone = userService.getUserByPhone(phone);
            Integer uid = userByPhone.getUid();
            user.setUid(uid);
            //3.通过uid修改用户信息
            int b = userService.updateUser(user);
            if (b == 0) {
                //修改失败
                return new Result(444, "修改失败", "服务器内部错误");
            }
            return new Result(200, "获取成功", b);

        }
        return new Result(444, "修改失败", "token过期");
    }


    /**
     * 通过token修改用户的贷款信息
     *
     * @param borrowerInfo //前端传的贷款信息表
     * @return
     */
    @RequestMapping("/updateUser")
    public Result updateUser(@RequestBody BorrowerInfo borrowerInfo) {
        String token = borrowerInfo.getUser().getToken();
        //根据token解析claims
        Claims claims = jwtUntil.parseToken(token);
        if (claims != null) {
            //1.获取到手机号
            String phone = claims.getSubject();
            //2.通过手机号查询uid
            Integer uid = userService.getUserByPhone(phone).getUid();
            //3.通过uid修改个人贷款信息
            borrowerInfo.setUserId(uid);
            int i = userService.updateBorrowerInfoById(borrowerInfo);
            if (i == 0) {
                return new Result(444, "修改失败", "系统错误");
            }
            return new Result(200, "修改成功", "修改成功");
        }
        return new Result(444, "修改失败", "token过期");
    }

    /**
     * 通过token获取uid
     * @param token
     * @return
     */
    @PostMapping("/getUid")
    public Integer getUid(String token) {
        Claims claims = jwtUntil.parseToken(token);
        if (claims != null) {
            //1.获取到手机号
            String phone = claims.getSubject();
            //2.通过手机号查询uid
            return userService.getUserByPhone(phone).getUid();
        }
        return null;
    }
}